/**
 * 
 */
package compilador.analizadorSintactico.categoriasSintacticas;

import java.util.ArrayList;

import javax.swing.tree.DefaultMutableTreeNode;

import compilador.analizadorLexico.simbolos.SimboloLexico;
import compilador.analizadorSemantico.tablaSimbolos.TablaSimboloSemantico;

/**
 * @author Nolberto Castellanos Rodriguez
 * @author Yurani Alejandra Salamanca Lotero
 *
 * Clase que representa la declaracion de una  funcion
 */
public class Metodo {

//	-------------------------------------------------------------------------------------------------
//	ATRIBUTOS
//	-------------------------------------------------------------------------------------------------
	
	/**
	 *  Atributo que representa la visibilidad de una funcion
	 */
	private Visibilidad visibilidad;
	
	/**
	 *  Atributo que contiene el valor del tipo de dato de la funcion
	 */
	private TipoDato tipoDato;
	
	/**
	 * Atributo que representa el identificador de una funcion
	 */
	private SimboloLexico identificadorMetodo;
	
	/**
	 * Atributo que representa la lista de parametros de una funcion
	 */
	private ListaParametros listaParametros;
	
	/**
	 * Atributo que representa el bloque de codigo de una funcion
	 */
	private BloqueSentencias bloqueSentencias;


//	-------------------------------------------------------------------------------------------------
//	CONSTRUCTOR
//	-------------------------------------------------------------------------------------------------
	
	/**
	 * Constructor que permite crear una Funcion
	 * @param visibilidad. Visibilidad del metodo
	 * @param tipoDato. Tipo de dato de la funcion
	 * @param identificadorMetodo. Identificador de variable de la funcion
	 * @param listaParametros. Lista de parametros de la funcion
	 * @param bloqueSentencias. Bloque de sentencias que tiene la funcion
	 */
	public Metodo(Visibilidad visibilidad, TipoDato tipoDato, SimboloLexico identificadorMetodo,
			ListaParametros listaParametros,
			BloqueSentencias bloqueSentencias) {
		super();
		this.visibilidad = visibilidad;
		this.tipoDato = tipoDato;
		this.identificadorMetodo = identificadorMetodo;
		this.listaParametros = listaParametros;
		this.bloqueSentencias = bloqueSentencias;
	}

	
//	-------------------------------------------------------------------------------------------------
//	METODOS
//	-------------------------------------------------------------------------------------------------	

	/**
	 * @return
	 */
	public String getJavaCode() {
		String retornable = "";
		
		if (visibilidad != null) {
			retornable += visibilidad.getJavaCode()+" ";
		}
		
		if (tipoDato != null)
			retornable += tipoDato.getJavaCode()+" ";
		
		if (identificadorMetodo != null)
			retornable+= identificadorMetodo.getLexema();
		
		retornable += "(";
		
		if (listaParametros != null) 
			retornable += listaParametros.getJavaCode();
		
		retornable += "){\n";
		
		if (bloqueSentencias != null)
			retornable += bloqueSentencias.getJavaCode();
		
		retornable+= "}";
		
		return retornable;
	}
	
	/**
	 * Metodo que permite agregar hojas al nodo de la clase
	 * @return el nodo de la clase con sus hojas
	 */
	public  DefaultMutableTreeNode getArbolVisual(){
		DefaultMutableTreeNode miRaiz =  new  DefaultMutableTreeNode("Funcion");
		
		if(visibilidad!=null)
		{
			miRaiz.add(visibilidad.getArbolVisual());
		}
		if(tipoDato!=null)
		{
			miRaiz.add(tipoDato.getArbolVisual());
		}
		miRaiz.add(new DefaultMutableTreeNode(identificadorMetodo.getLexema()));

		if(listaParametros!=null)
		{
			miRaiz.add(listaParametros.getArbolVisual());
		}
		if(bloqueSentencias!=null)
		{
			miRaiz.add(bloqueSentencias.getArbolVisual());
		}
		
		return miRaiz;
	}
	


	/**
	 * @param ts
	 * @param errores
	 * @param claseActual
	 * @param metodoActual
	 */
	public void analizarSemantica(TablaSimboloSemantico ts,	ArrayList<SimboloError> errores, String claseActual, String metodoActual) {
		if (bloqueSentencias != null) 
			bloqueSentencias.AnalizarSemantica(ts, errores, claseActual, identificadorMetodo.getLexema());
	}
	
	
//	-------------------------------------------------------------------------------------------------
//	Getters and Setters
//	-------------------------------------------------------------------------------------------------
	


	/**
	 * Metodo que nos retorna el valor de visibilidad
	 * @return  visibilidad. Valor retornado
	 */
	public Visibilidad getVisibilidad() {
		return visibilidad;
	}


	/**
	 * Metodo que permite asignar el valor de visibilidad
	 * @param visibilidad. Valor a asignar visibilidad
	 */
	public void setVisibilidad(Visibilidad visibilidad) {
		this.visibilidad = visibilidad;
	}


	/**
	 * Metodo que nos retorna el valor de tipoDato
	 * @return  tipoDato. Valor retornado
	 */
	public TipoDato getTipoDato() {
		return tipoDato;
	}


	/**
	 * Metodo que permite asignar el valor de tipoDato
	 * @param tipoDato. Valor a asignar tipoDato
	 */
	public void setTipoDato(TipoDato tipoDato) {
		this.tipoDato = tipoDato;
	}


	/**
	 * Metodo que nos retorna el valor de identificadorMetodo
	 * @return  identificadorMetodo. Valor retornado
	 */
	public SimboloLexico getIdentificadorMetodo() {
		return identificadorMetodo;
	}


	/**
	 * Metodo que permite asignar el valor de identificadorMetodo
	 * @param identificadorMetodo. Valor a asignar identificadorMetodo
	 */
	public void setIdentificadorMetodo(SimboloLexico identificadorMetodo) {
		this.identificadorMetodo = identificadorMetodo;
	}


	/**
	 * Metodo que nos retorna el valor de listaParametros
	 * @return  listaParametros. Valor retornado
	 */
	public ListaParametros getListaParametros() {
		return listaParametros;
	}


	/**
	 * Metodo que permite asignar el valor de listaParametros
	 * @param listaParametros. Valor a asignar listaParametros
	 */
	public void setListaParametros(ListaParametros listaParametros) {
		this.listaParametros = listaParametros;
	}


	/**
	 * Metodo que nos retorna el valor de bloqueSentencias
	 * @return  bloqueSentencias. Valor retornado
	 */
	public BloqueSentencias getBloqueSentencias() {
		return bloqueSentencias;
	}


	/**
	 * Metodo que permite asignar el valor de bloqueSentencias
	 * @param bloqueSentencias. Valor a asignar bloqueSentencias
	 */
	public void setBloqueSentencias(BloqueSentencias bloqueSentencias) {
		this.bloqueSentencias = bloqueSentencias;
	}

}
